/*
 * Unit tests for the Subscriber class
 * @author M.A. Taupenot
 * @version 1.0.0
 * 25/05/2012
 */
package tests;

import static org.junit.Assert.assertTrue;
import org.junit.*;

import java.util.*;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

import jpaUtils.JPAUtil;

import loansManagement.Loan;
import loansManagement.LoanDAO;
import main.Library;
import subscribersManagement.Entitled;
import subscribersManagement.Subscriber;
import subscribersManagement.SubscriberDAO;
import subscribersManagement.UtilsDate;
import booksManagement.Book;
import booksManagement.BookDAO;
import booksManagement.CopyDAO;
import booksManagement.DVD;
import booksManagement.Copy;
import booksManagement.DvdDAO;
import booksManagement.MediaDAO;
import exceptions.*;

/**
 * @author   user
 */
public class SubscriberTest
{
	private Scanner scanStr = new Scanner(System.in);
	private Scanner scanInt = new Scanner(System.in);
	
	/**
   * @uml.property  name="subscriberDAO"
   * @uml.associationEnd  
   */
	private SubscriberDAO subscriberDAO;
	/**
   * @uml.property  name="bookDAO"
   * @uml.associationEnd  
   */
	private static Library lib = new Library();
	/**
   * @return
   * @uml.property  name="bookDAO"
   */
	public static Library getLib(){
		return lib;
	}
	/**
   * @uml.property  name="bookDAO"
   * @uml.associationEnd  
   */
	private BookDAO bookDAO;
	/**
   * @uml.property  name="copyDAO"
   * @uml.associationEnd  
   */
	private CopyDAO copyDAO;
	/**
   * @uml.property  name="loanDAO"
   * @uml.associationEnd  
   */
	private LoanDAO loanDAO = new LoanDAO();
	/**
   * @uml.property  name="dvdDAO"
   * @uml.associationEnd  
   */
	private DvdDAO dvdDAO;
	/**
   * @uml.property  name="mediaDAO"
   * @uml.associationEnd  
   */
	private MediaDAO mediaDAO;
	private List<String> authors1= new ArrayList<String>();;
	private List<String> authors2= new ArrayList<String>();;

	private void createMedias() throws BadParametersException {
		EntityManager em;
		EntityTransaction tx;		
		bookDAO = new BookDAO();
		mediaDAO = new MediaDAO();
		dvdDAO = new DvdDAO();
		copyDAO= new CopyDAO();
		
		em= JPAUtil.getEntityManager();
		tx=em.getTransaction();
		tx.begin();
		
		if (bookDAO.isEmpty() && mediaDAO.isEmpty() && dvdDAO.isEmpty() ) {
			System.out.println("===== Create Media data in memory ====");
			authors1.add("Elmasri");
			authors1.add("Navathe");
			authors2.add("Peter Gulutzan");
			authors2.add("Trudy Pelzer");
			Book b1 = new Book("Fundamentals of Database Systems", authors1, new GregorianCalendar(), "0-321-20228-4");
			Book b2 = new Book("SQL-99 Complete, Really", authors2, new GregorianCalendar(), "0-87930-568-1");
			DVD d1 = new DVD("La guerre des boutons", new GregorianCalendar(),"0654744657",2);
			DVD d2 = new DVD("Microcosmos", new GregorianCalendar(),"136658783");
			Book b3 = new Book("Pandore menacée", new ArrayList<String>(), UtilsDate.asCalendar(UtilsDate.stringToDate("12/11/2004")), "978-2-8112-0036-7", 5);
			b1.addCopy();
			d1.addCopy();
			Copy cb1 = b1.getCopies().get(0);
			Copy cd1 = d1.getCopies().get(2);
			System.out.println("===== Persist media data ====");
			try {
				mediaDAO.add(b1);
				mediaDAO.add(b2);
				lib.addMedia(b3);
				mediaDAO.add(d1);
				mediaDAO.add(d2);
				copyDAO.add(cd1);
				copyDAO.add(cb1);
				
			} catch (Exception pe) {
				System.err.println("Exception when persisting data");
				JPAUtil.closeEntityManager();
				pe.printStackTrace();
			}
		}
		System.out.println("===== Display media data =====");
		System.out.println("Nombre de medias : " + mediaDAO.getContent().size());
		System.out.println(mediaDAO.toString());
		System.out.println("===== Display copy data =====");
		System.out.println(copyDAO.toString());
		tx.commit();
		JPAUtil.closeEntityManager();

	}


	private void createSubscribers() throws BadParametersException {
		EntityManager em;
		EntityTransaction tx;		

		em= JPAUtil.getEntityManager();
		tx=em.getTransaction();
		tx.begin();

		subscriberDAO = new SubscriberDAO();
		if (subscriberDAO.isEmpty()) {
			System.out.println("===== Create Subscriber data in memory ====");
			Subscriber 	s1 = new Subscriber("Vincent", "Airo", new GregorianCalendar(1960, 12, 13));
			Subscriber 	s2 = new Subscriber("Betina", "Chtilfiz", new GregorianCalendar(1965, 02, 25));
			Entitled 	s3 = new Entitled("Victor", "Chtilfiz", new GregorianCalendar(1997, 02, 20), s2);
			Entitled 	s4 = new Entitled("Luisa", "Chtilfiz", new GregorianCalendar(1993, 07, 30), s2);
			System.out.println("===== Persist Subscriber data ====");
			try {
				subscriberDAO.add(s1);
				subscriberDAO.add(s2);
				subscriberDAO.add(s3);
				subscriberDAO.add(s4);
			} catch (Exception pe) {
				System.err.println("Exception when persisting data");
				JPAUtil.closeEntityManager();
				pe.printStackTrace();
			}
		}
		System.out.println("===== Display Subscriber data =====");
		System.out.println(subscriberDAO.toString());

		tx.commit();
		JPAUtil.closeEntityManager();
	}
	

	
	@Before
	public void beforeTests() throws BadParametersException, TooManyLoansException, LentBookException, SubscriberExistsException, BookExistsException, ReservedCopyException  {
		createSubscribers();
		createMedias();
		lib.setMedias(mediaDAO);
		lib.setCopies(copyDAO);
		lib.setSubscribers(subscriberDAO);
		lib.setLoans(loanDAO);
	}
	
	@Test
	public void testAddSubscriber() throws SubscriberExistsException{
		EntityManager em;
		EntityTransaction tx;
		
		
		System.out.println("Number of subscribers before add : " + lib.getSubscribers().getContent().size());
		System.out.println("First Name ?");
		String firstName = scanStr.nextLine();
		System.out.println("Last Name ?");
		String lastName = scanStr.nextLine();
		System.out.println("birthDate (dd/mm/yyyy) ?");
		Date birthDate = UtilsDate.stringToDate(scanStr.nextLine());
		GregorianCalendar birthDAte = UtilsDate.asCalendar(birthDate);
		em= JPAUtil.getEntityManager();
		tx=em.getTransaction();
		try{
		Subscriber s = new Subscriber(firstName, lastName, birthDAte);
		
		
		tx.begin();
		
		long subscriber_id=lib.addSubscriber(s);
		tx.commit();
		}catch(BadParametersException e){
			System.out.println("Problem with parameters");
			e.printStackTrace();
		}
		
		
		JPAUtil.closeEntityManager();
	}
	
	@Test
	public void testChildDvdLoan() throws SubscriberExistsException, BadParametersException, BookExistsException, LentBookException, TooManyLoansException{
		System.out.println(lib.getSubscribers().get(3));
		Subscriber s = lib.getSubscribers().get(3);
		try{
		lib.lend(lib.getCopies().get(10), s);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	@Test
	public void testChildBookLoan() throws SubscriberExistsException, BadParametersException, BookExistsException, LentBookException, TooManyLoansException, ReservedCopyException{
		EntityManager em;
		EntityTransaction tx;
		
		System.out.println(lib.getSubscribers().get(3));
		Subscriber s = lib.getSubscribers().get(3);
		em= JPAUtil.getEntityManager();
		tx=em.getTransaction();
		try{
		
		tx.begin();
		
		lib.lend(lib.getCopies().get(6), s);
		
		tx.commit();
		}catch(TooManyLoansException e){
			e.printStackTrace();
		}
		
		
		JPAUtil.closeEntityManager();

		
	}
	
	@Test
	public void testAdultTooManyLoans() throws SubscriberExistsException, BadParametersException, BookExistsException, LentBookException, ReservedCopyException{
		EntityManager em;
		EntityTransaction tx;
		System.out.println(lib.getSubscribers().get(1));
		Subscriber s = lib.getSubscribers().get(1);
		em= JPAUtil.getEntityManager();
		tx=em.getTransaction();
		
		try{
			
			tx.begin();
			
			lib.addMediaCopy(lib.getMedias().get("0-87930-568-1"), 2);
			lib.addMediaCopy(lib.getMedias().get("136658783"), 3);
			tx.commit();
			tx.begin();
			lib.lend(lib.getCopies().get(7), s);
			lib.lend(lib.getCopies().get(9), s);
			lib.lend(lib.getCopies().get(8), s);
			lib.lend(lib.getCopies().get(10), s);
			lib.lend(lib.getCopies().get(11), s);
			lib.lend(lib.getCopies().get(12), s);
			lib.lend(lib.getCopies().get(13), s);
			tx.commit();
			}catch(TooManyLoansException e){
				e.printStackTrace();
				System.out.println("nombre d'emprunts en cours :" +s.getCurrentLoans().size());
				System.out.println("DVD :" + s.getDvdLoanedNb());
				System.out.println("Books" + s.getBooksLoanedNb());
			}
			
			JPAUtil.closeEntityManager();		
		
	}
	
	@Test
	public void test1YearSubscriber() throws SubscriberExistsException, BadParametersException, BookExistsException, LentBookException, ReservedCopyException{
		EntityManager em;
		EntityTransaction tx;
		
		Subscriber s = lib.getSubscribers().get(1);
		Calendar sub = s.getSubscriptionDate();
		sub.add(Calendar.YEAR, -1);
		s.setSubscriptionDate(sub);
		s.setBooksLoanedNb(5);
		System.out.println(s.getBooksLoanedNb());
		System.out.println("try lend next book");
		
		em= JPAUtil.getEntityManager();
		tx=em.getTransaction();
		
		try{
			tx.begin();
			lib.addMediaCopy(lib.getMedias().get("0-87930-568-1"), 2);
			lib.lend(lib.getCopies().get(6), s);
			tx.commit();
			System.out.println(s.getBooksLoanedNb());
		}catch(TooManyLoansException e){
			e.printStackTrace();
		}
		JPAUtil.closeEntityManager();
		
	}
	
	@Test
	public void test2YearSubscriber() throws SubscriberExistsException, BadParametersException, BookExistsException, LentBookException, ReservedCopyException{
		EntityManager em;
		EntityTransaction tx;
		
		Subscriber s = lib.getSubscribers().get(1);
		Calendar sub = s.getSubscriptionDate();
		sub.add(Calendar.YEAR, -2);
		s.setSubscriptionDate(sub);
		s.setBooksLoanedNb(7);
		System.out.println(s.getBooksLoanedNb());
		System.out.println("try lend next book");
		
		em= JPAUtil.getEntityManager();
		tx=em.getTransaction();
		
		try{
			tx.begin();
			lib.addMediaCopy(lib.getMedias().get("0-87930-568-1"), 2);
			lib.lend(lib.getCopies().get(8), s);
			tx.commit();
		}catch(TooManyLoansException e){
			e.printStackTrace();
		}
		JPAUtil.closeEntityManager();
		
	}

}
